﻿using System;
using System.Collections.Generic;
using WAD.Model;
using WAD.DAL;
using WAD.WEB.AppCode;
using WAD.WEB.AppCode.WxPay.Pay;
using WAD.BLL;
using System.Text.RegularExpressions;
using WAD.WEB.AppCode.Pay.AlipayFk;
using System.Threading;
using System.Text;


namespace WAD.WEB.Admin.Ajax
{
    /// <summary>
    /// 提现接口
    /// </summary>
    public class FC_Cash : AdminAjax
    {
        public override void AjaxMethodDispatch(String identity)
        {
            switch (identity)
            {
                case "getlist": this.GetList(); break;
                case "getlist_ali": this.GetList_Ali(); break;
                case "check_ali": this.Check_Ali(); break;
                case "setcallbackstate": this.SetCallbackState(); break;
                case "check": this.Check(); break;
            }
        }
        /// <summary>
        /// 提现列表
        /// </summary>
        [QD.Web.Ajax.AjaxMethod]
        public void GetList()
        {
            int userid = Parse.Int("userid", 0);
            int state = Parse.Int("state", -1);
            int platform = Parse.Int("platform", -1);
            int page = Parse.Int("page_index", 1);//当前页
            int pageSize = Parse.Int("pagesize", 20);//当前页
            var mchid = Parse.String("mchid", "");
            string starttime = Parse.String("starttime", "");
            string endtime = Parse.String("endtime", "");
            StringBuilder sb = new StringBuilder();

            sb.Append("1=1");
            if (state > -1)
                sb.AppendFormat(" and [state] ={0} ", state);
            if (platform > -1)
                sb.AppendFormat(" and [platform] ={0} ", platform);
            if (userid != 0)
                sb.AppendFormat(" and [user_id] = {0}", userid);
            if (!string.IsNullOrEmpty(mchid))
                sb.AppendFormat("and wx_mchid='{0}'", mchid);
            if (starttime.Length > 0)
                sb.AppendFormat(" and date>'{0}'", starttime);
            if (endtime.Length > 0)
                sb.AppendFormat(" and date<='{0}'", Convert.ToDateTime(endtime).AddDays(1).ToString("yyyy-MM-dd"));

            PageData dt = WAD.DAL.DAOFCCash.GetPageList(page, pageSize, sb.ToString(), "*");
            if (dt.table.Rows.Count == 0)
                DataEmpty();
            JsonResult(0, "", dt);
        }

        [QD.Web.Ajax.AjaxMethod]
        public void GetList_Ali()
        {
            int page = Parse.Int("page_index", 1);//当前页
            int pageSize = Parse.Int("pagesize", 20);//当前页
            int user_id = Parse.Int("userid", 0);
            int state = Parse.Int("state", 0);  //状态(0 未审核, 1 已审核,2 已拒绝)
            int platform = Parse.Int("platform", -1);
            string starttime = Parse.String("starttime", "");
            string endtime = Parse.String("endtime", "");

            StringBuilder sb = new StringBuilder();
            sb.Append("1=1");
            if (user_id > 0)
                sb.AppendFormat(" and user_id={0}", user_id);
            if (platform > -1)
                sb.AppendFormat(" and platform={0}", platform);

            if (state > -2)
                sb.AppendFormat(" and state={0}", state);

            if (starttime.Length > 0)
                sb.AppendFormat(" and date>'{0}'", starttime);
            if (endtime.Length > 0)
                sb.AppendFormat(" and date<='{0}'", endtime);

            PageData pg = WAD.DAL.DAOFCCash.GetListPage("*", "id desc", page, pageSize, sb.ToString(), "v_fc_cash_setting");
            if (pg.table.Rows.Count == 0)
                DataEmpty();
            JsonResult(0, "", pg);
        }

        #region 支付宝提现(申请)

        [QD.Web.Ajax.AjaxMethod]
        public void Check_Ali()
        {
            string ids = Parse.String("ids", "");
            int pageSize = Parse.Int("pagesize", 500);
            StringBuilder sb = new StringBuilder();

            if (ids.Length < 1)
                ParamError();

            if (!CheckCaiWu())
                JsonResult(11, "您无提现操作权限");


            sb.Append("state=0 and ali_name!='' and ali_truename!=''");
            sb.Append(" and id in (" + ids + ")");

            //获取选中的用户
            List<Dictionary<string, object>> user = DAOFCCash.GetList(sb.ToString(), "[user_id],orderid,amount,date,ali_name,ali_truename", pageSize, "v_fc_cash_setting");

            //生成支付宝用户列表
            List<AlipayFkModel> list = GetList_Ali(user);
            if (list == null)
                JsonResult(11, "没有提现的用户");

            //业务号(格式：当天日期[8位]+序列号[3至16位]，如：201008010000001)
            String batchNo = DateTime.Now.ToString("yyyyMMdd") + DateTime.Now.ToString("yyyyMMddHHmmss");
            //回调地址
            String notifyUrl = string.Format("http://{0}/client/api/alitx_notify.aspx", Request.Url.Authority);

            if (list.Count == 0)
                JsonResult(11, "请选择提现用户");


            DAOFCCash.SetCallback_State(ids, 2);    //锁定记录，等待第三方回调

            //批量提现
            string html = AlipayFkUtil.Pay(notifyUrl, batchNo, list);
            Response.Write(html);
        }

        List<AlipayFkModel> GetList_Ali(List<Dictionary<string, object>> user)
        {
            if (user == null) return null;
            List<AlipayFkModel> list = new List<AlipayFkModel>();
            for (int i = 0; i < user.Count; i++)
            {
                AlipayFkModel m = new AlipayFkModel()
                {
                    AlipayAcount = Convert.ToString(user[i]["ali_name"]),
                    AlipayName = Convert.ToString(user[i]["ali_truename"]),
                    Money = Convert.ToDouble(user[i]["amount"]),
                    Remark = Convert.ToString(user[i]["user_id"]),
                    SerialNumber = Convert.ToString(user[i]["orderid"])
                };
                list.Add(m);
                Thread.Sleep(1);
            }
            return list;
        }


        /// <summary>
        /// 设置提现的回调状态
        /// </summary>
        [QD.Web.Ajax.AjaxMethod]
        public void SetCallbackState()
        {
            string ids = Parse.String("ids", "");
            int state = Parse.Int("callback_state", 0);
            if (state < 1 || string.IsNullOrEmpty(ids))
                ParamError();
            //每次发审核前,先标记成2状态,一旦收到回调,改成1状态
            DAOFCCash.SetCallback_State(ids, state);
            Success();
        }

        #endregion

        #region 微信提现

        [QD.Web.Ajax.AjaxMethod]
        public void Check()
        {
            int id = Parse.Int("id", 0);
            int type = Parse.Int("type", 0);    // 1通过，2拒绝
            int adminid = 0;    //管理员ID
            if (!string.IsNullOrEmpty(Request.Cookies["adminid"].Value))
                adminid = Convert.ToInt32(Request.Cookies["adminid"].Value);

            if (!CheckCaiWu())
                JsonResult(11, "您无提现操作权限");

            Dictionary<string, object> model = DAOFCCash.Get("fc_cash", "id=" + id, "id,user_id,orderid,amount,platform,record_id,state,openid,wx_appid");
            if (model == null)
                JsonResult(Message.Code.DATA_EMPTY, "找不到记录");

            int user_id = Convert.ToInt32(model["user_id"]);
            decimal amount = Convert.ToDecimal(model["amount"]);
            if (type == 1)
            {
                //提现
                string callback_msg = "";
                int record_id = 0;
                if (model["record_id"] != DBNull.Value)
                    record_id = Convert.ToInt32(model["record_id"]);    //广告主提现记录ID

                //发起请求
                string msg = TiXian(user_id, amount, Convert.ToInt32(model["platform"]), record_id, Convert.ToInt32(model["state"]), Convert.ToString(model["openid"]), Convert.ToString(model["orderid"]),model["wx_appid"].ToString(), out callback_msg);

                if (string.IsNullOrEmpty(msg))
                    DAOFCCash.Check(1, id, adminid, callback_msg);      //标记成已审核状态
                else
                    JsonResult(11, msg); //提现出现错误
            }
            else if (type == 2)
            {
                //拒绝
                Back(id, user_id, amount, Convert.ToInt32(model["state"]), adminid);
            }
            else if (type == 3)
            {
                //撤销
                Cancel(id, user_id, amount, adminid, Convert.ToString(model["orderid"]));
            }
            else
                JsonResult(11, "无效的操作");

            JsonResult(0, "");
        }

        /// <summary>
        /// 微信提现(网络请求)
        /// </summary>
        string TiXian(int user_id, decimal amount, int platform, int record_id, int state, string openId, string tradeNo,string wx_appid, out string callback_msg)
        {
            callback_msg = "";
            int money = Convert.ToInt32(amount * 100);      //提现金额，单位是分，微信规定: 最小提现金额1元

            if (state > 0) return "不允许重复审核";

            if (money < 100) return "提现金额无效";

            if (string.IsNullOrEmpty(tradeNo)) return "订单号无效";

            //获取用户账户余额
            Dictionary<string, object> user = DaoUser.GetDetail(user_id, "ad_balance,shared_balance,is_validate_phone");

            if (user["is_validate_phone"] == DBNull.Value || Convert.ToInt32(user["is_validate_phone"]) != 1)
                return "手机号未验证";

            string msg = "";
            decimal balance = 0;

            //微信提现
            if (platform == 1)
            {
                try
                {
                    //检查是否重复提现
                    //string xml = PayToWx.GetTransferInfo(tradeNo);

                    //扣除余额(从分享余额中扣)
                    //int count = DaoUser.UpdateBalance(user_id, (balance - amount), 2);
                    //callback_msg = string.IsNullOrEmpty(wx_appid) ? PayToWx.Pay(openId, tradeNo, money) : PayToWx2.Pay(openId, tradeNo, money);
                    callback_msg =  PayToWx.Pay(openId, tradeNo, money);

                    if (IsSuccess(callback_msg))
                        msg = "";
                    else
                    {
                        msg = GetErrMsg(callback_msg);  //提现失败,显示错误消息

                        ////回滚余额
                        //if (count > 0)
                        //    DaoUser.UpdateBalance(user_id, balance, 2);
                    }

                    Log(openId, tradeNo, money*0.01, callback_msg, balance, amount/100);  //debug日志

                    Log(adminId, user_id, money*0.01, balance);                     //系统日志

                }
                catch (Exception ex) { msg = ex.Message; }
            }
            else if (platform == 2)
            {
                //支付宝提现
                return "支付宝提现暂未开通";
            }
            return msg;
        }

        //拒绝提现
        void Back(int id, int user_id, decimal amount, int state, int adminid)
        {
            if (state > 0)
                JsonResult(11, "已审核的记录不允许操作");
            //拒绝
            DAOFCCash.Check(2, id, adminid, "");         //标记成拒绝状态
            //写日志
            DAOLog.Add(string.Format("拒绝提现【微街秀ID:{0},提现金额:{1}】", user_id, amount), adminid, user_id);
        }

        /// <summary>
        /// 撤销提现
        /// </summary>
        void Cancel(int id, int user_id, decimal amount, int adminid, string orderid)
        {
            Dictionary<string, object> user = DaoUser.GetDetail(user_id, "shared_balance");
            decimal balance = Convert.ToDecimal(DaoUser.BalanceDncode(user["shared_balance"], WJXConfig.EncryptConfig.DES_KEY));
            bool isErr = false;
            int count1 = 0, count2 = 0;
            try
            {
                //退回金额给分享主
                count1 = DaoUser.UpdateBalance(user_id, balance + amount, 2);

                //删除提现记录
                if (count1 > 0)
                    count2 = DAOFCCash.Delete(user_id, orderid);
            }
            catch { isErr = true; }

            if (isErr && count1 > 0)
                DaoUser.UpdateBalance(user_id, balance, 2);

            //日志
            DAOLog.Add(string.Format("撤销提现【微街秀ID:{0},单笔金额:{1},撤销后余额:{2}】", user_id, amount, balance + amount), adminid, user_id);

            if (count2 > 0)
                Success();
            Fail();
        }

        bool IsSuccess(string xml)
        {
            Regex r1 = new Regex("<result_code>([\\s\\S]+)</result_code>"); //业务结果（SUCCESS / FAIL）
            //交易状态 (SUCCESS : 转账成功 / FAILED:转账失败 / PROCESSING:处理中)
            if (r1.IsMatch(xml))
            {
                if (r1.Match(xml).Value.ToUpper().IndexOf("SUCCESS") > -1)
                    return true;
            }
            return false;
        }

        string GetErrMsg(string xml)
        {
            Regex r1 = new Regex("<return_msg>([\\s\\S]+)</return_msg>");
            var r2=new Regex("<err_code_des>([\\s\\S]+)</err_code_des>");
            var r3= new Regex("<mchid>([\\s\\S]+)</mchid>");
            var errdes = r2.Match(xml).Groups[1].Value.Replace("<![CDATA[", "").Replace("]]>", "");
            var mchid= r3.Match(xml).Groups[1].Value.Replace("<![CDATA[", "").Replace("]]>", "");
            if (r1.IsMatch(xml))
                return "微信账户错误：" + r1.Match(xml).Groups[1].Value.Replace("<![CDATA[", "").Replace("]]>", "")+" "+errdes+"商户ID："+mchid;
            return "";
        }

        void Log(string openId, string tradeNo, double money, string callback_msg, decimal balance, decimal amount)
        {
            SavaLog("wx_tixian", string.Format("提现参数:【openId={0}&tradeNo={1}&money={2}】,余额：【支付前余额:{4},后余额:{5}】,返回值:{3}", openId, tradeNo, money, callback_msg, balance, (balance - amount)));
        }

        void Log(int adminid, int user_id, double money, decimal balance)
        {
            DAOLog.Add(string.Format("微信提现【微街秀ID:{0},提现金额:{1},余额:{2}】", user_id, money, balance), adminid, user_id);
        }
        
        #endregion

    }
}